package com.base.common.model.dto;

import com.base.common.constants.HeaderConstants;
import com.base.common.enums.ErrorEnum;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.FieldNameConstants;

/**
 * 通用Dto结果
 *
 * @author admin
 * @date 2020/9/4 下午3:13
 */
@Data
@ToString
@ApiModel(value = "BaseDto", description = "通用Dto结果")
@FieldNameConstants
@JsonIgnoreProperties(ignoreUnknown = true)
public class BaseDto {
    /**
     * 处理结果代码
     * <p>
     * 取值描述：
     * 0 - 无任何问题，业务交互成功；
     * ……其他取值参照具体接口错误描述。
     */
    @ApiModelProperty(notes = "处理结果代码: 0 - 无任何问题，交互成功；非0 - 交互异常，具体原因见respMsg；")
    private String respCode;

    /**
     * 处理结果代码描述，当respCode=0时，respMsg=SUCCESS，其他情况返回描述信息，用于系统提示
     */
    @ApiModelProperty(notes = "处理结果代码描述，当respCode=0时，respMsg=SUCCESS，其他情况返回描述信息，用于系统提示")
    private String respMsg;

    public BaseDto() {
        this.respCode = HeaderConstants.STATUS_SUCCESS;
    }

    public BaseDto(String respCode, String respMsg) {
        this.respCode = respCode;
        this.respMsg = respMsg;
    }

    public BaseDto(ErrorEnum errorEnum) {
        this.respCode = errorEnum.getCode();
        this.respMsg = errorEnum.getCodeMsg();
    }

    /**
     * 设置响应成功
     */
    public void setSuccess() {
        this.respCode = HeaderConstants.STATUS_SUCCESS;
        this.respMsg = HeaderConstants.STATUS_SUCCESS_MSG;
    }

    /**
     * 设置响应失败
     */
    public void setFailure(String respCode, String respMsg) {
        if (HeaderConstants.STATUS_SUCCESS.equals(respCode)) {
            throw new IllegalArgumentException("不能使用成功状态码");
        }
        this.respCode = respCode;
        this.respMsg = respMsg;
    }

    /**
     * 设置响应失败状态
     *
     * @param errorEnum 状态码
     */
    public void setFailure(ErrorEnum errorEnum) {
        if (HeaderConstants.STATUS_SUCCESS.equals(errorEnum.getCode())) {
            throw new IllegalArgumentException("不能使用成功状态码");
        }

        this.respCode = errorEnum.getCode();
        this.respMsg = errorEnum.getCodeMsg();
    }

    /**
     * 响应对象
     *
     * @param respCode code
     * @param respMsg  mgs
     * @return 响应对象
     */
    private static BaseDto build(String respCode, String respMsg) {
        BaseDto baseDto = new BaseDto();
        baseDto.setRespCode(respCode);
        baseDto.setRespMsg(respMsg);
        return baseDto;
    }

    /**
     * 设置响应成功状态
     *
     * @param msg 成功提示信息
     * @return 当前响应对象
     */
    public static BaseDto buildSuccess(String msg) {
        return build(HeaderConstants.STATUS_SUCCESS, msg);
    }

    /**
     * 设置响应成功状态，提示信息使用：SUCCESS
     *
     * @return 当前响应对象
     */
    public static BaseDto buildSuccess() {
        return buildSuccess(HeaderConstants.STATUS_SUCCESS_MSG);
    }

    /**
     * 设置响应失败状态
     *
     * @return 当前响应对象
     */
    public static BaseDto buildFailure() {
        return build(HeaderConstants.STATUS_FAILURE, "失败");
    }

    /**
     * 设置响应失败状态
     *
     * @param msg 错误提示信息
     * @return 当前响应对象
     */
    public static BaseDto buildFailure(String msg) {
        return build(HeaderConstants.STATUS_FAILURE, msg);
    }

    /**
     * 设置响应失败状态
     *
     * @param code 状态码
     * @param msg  错误提示信息
     * @return 当前响应对象
     */
    public static BaseDto buildFailure(String code, String msg) {
        if (HeaderConstants.STATUS_SUCCESS.equals(code)) {
            throw new IllegalArgumentException("不能使用成功状态码");
        }
        return build(code, msg);
    }

    /**
     * 设置响应失败状态
     *
     * @param errorEnum 状态码
     * @return 当前响应对象
     */
    public static BaseDto buildFailure(ErrorEnum errorEnum) {
        return buildFailure(errorEnum.getCode(), errorEnum.getCodeMsg());
    }

    /**
     * 检测成功状态
     *
     * @param baseDto 状态码
     * @return boolean baseDto为null或baseDto.respCode不为0，返回false；
     */
    public static Boolean checkSuccess(BaseDto baseDto) {
        return baseDto == null ? Boolean.FALSE : (HeaderConstants.STATUS_SUCCESS.equals(baseDto.getRespCode()) ? Boolean.TRUE : Boolean.FALSE);
    }
}